home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 February
/
EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso
/
enigma
/
earcd
/
varie
/
uae-0_64.lha
/
uae-0.6.4
/
src
/
include
/
newcpu.h
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-03
|
6KB
|
264 lines
/*
* UAE - The Un*x Amiga Emulator
*
* MC68000 emulation
*
* Copyright 1995 Bernd Schmidt
*/
extern int areg_byteinc[];
extern int imm8_table[];
extern int movem_index1[256];
extern int movem_index2[256];
extern int movem_next[256];
extern int fpp_movem_index1[256];
extern int fpp_movem_index2[256];
extern int fpp_movem_next[256];
extern int broken_in;
typedef void cpuop_func(ULONG) REGPARAM;
struct cputbl {
cpuop_func *handler;
int specific;
UWORD opcode;
};
extern struct cputbl smallcputbl[];
extern cpuop_func *cpufunctbl[65536];
extern void op_illg(ULONG) REGPARAM;
typedef char flagtype;
/* Arrrghh.. */
#if defined(USE_COMPILER) && !defined(USE_POINTER)
#define USE_POINTER
#undef NEED_TO_DEBUG_BADLY
#endif
#if defined(NEED_TO_DEBUG_BADLY) && !defined(USE_POINTER)
#define USE_POINTER
#endif
struct flag_struct {
unsigned int c:1; /* first byte */
int :5;
unsigned int z:1;
unsigned int n:1;
int :3;
unsigned int v:1; /* second byte */
int :4;
unsigned int x:1; /* third & fourth */
int :15;
};
extern struct regstruct
{
ULONG d[8];
CPTR a[8],usp,isp,msp;
UWORD sr;
flagtype t1;
flagtype t0;
flagtype s;
flagtype m;
flagtype x;
flagtype stopped;
int intmask;
ULONG pc;
#ifdef USE_POINTER
UBYTE *pc_p;
UBYTE *pc_oldp;
#endif
ULONG vbr,sfc,dfc;
double fp[8];
ULONG fpcr,fpsr,fpiar;
ULONG spcflags;
} regs, lastint_regs;
#ifdef INTEL_FLAG_OPT
extern struct flag_struct regflags __asm__ ("regflags");
#else
extern struct flag_struct regflags;
#endif
#define ZFLG (regflags.z)
#define NFLG (regflags.n)
#define CFLG (regflags.c)
#define VFLG (regflags.v)
#define XFLG (regflags.x)
#ifdef USE_POINTER
static __inline__ UWORD nextiword(void)
{
UWORD r = (*(regs.pc_p) << 8) | (*(regs.pc_p + 1) << 0);
regs.pc_p += 2;
return r;
}
static __inline__ ULONG nextilong(void)
{
ULONG r = (*regs.pc_p << 24) | (*(regs.pc_p + 1) << 16) | (*(regs.pc_p + 2) << 8) | (*(regs.pc_p + 3) << 0);
regs.pc_p += 4;
return r;
}
#else
static __inline__ UWORD nextiword(void)
{
UWORD r = get_aword(regs.pc);
regs.pc += 2;
return r;
}
static __inline__ ULONG nextilong(void)
{
ULONG r = get_along(regs.pc);
regs.pc += 4;
return r;
}
#endif
#ifdef USE_POINTER
#if !defined(NEED_TO_DEBUG_BADLY) && !defined(USE_COMPILER)
static __inline__ void m68k_setpc(CPTR newpc)
{
regs.pc = newpc;
regs.pc_p = regs.pc_oldp = get_real_address(newpc);
}
#else
extern void m68k_setpc(CPTR newpc);
#endif
static __inline__ CPTR m68k_getpc(void)
{
return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
}
#else
static __inline__ void m68k_setpc(CPTR newpc)
{
regs.pc = newpc;
}
static __inline__ CPTR m68k_getpc(void)
{
return regs.pc;
}
#endif
#ifdef USE_COMPILER
extern void m68k_setpc_fast(CPTR newpc);
extern void m68k_setpc_bcc(CPTR newpc);
extern void m68k_setpc_rte(CPTR newpc);
#else
#define m68k_setpc_fast m68k_setpc
#define m68k_setpc_bcc m68k_setpc
#define m68k_setpc_rte m68k_setpc
#endif
static __inline__ void m68k_setstopped(int stop)
{
regs.stopped = stop;
if (stop)
regs.spcflags |= SPCFLAG_STOP;
}
static __inline__ int cctrue(const int cc)
{
switch(cc){
case 0: return 1; /* T */
case 1: return 0; /* F */
case 2: return !CFLG && !ZFLG; /* HI */
case 3: return CFLG || ZFLG; /* LS */
case 4: return !CFLG; /* CC */
case 5: return CFLG; /* CS */
case 6: return !ZFLG; /* NE */
case 7: return ZFLG; /* EQ */
case 8: return !VFLG; /* VC */
case 9: return VFLG; /* VS */
case 10:return !NFLG; /* PL */
case 11:return NFLG; /* MI */
case 12:return NFLG == VFLG; /* GE */
case 13:return NFLG != VFLG; /* LT */
case 14:return !ZFLG && (NFLG == VFLG); /* GT */
case 15:return ZFLG || (NFLG != VFLG); /* LE */
}
abort();
return 0;
}
#if CPU_LEVEL > 1
static __inline__ ULONG get_disp_ea (ULONG base)
{
UWORD dp = nextiword();
int reg = (dp >> 12) & 7;
LONG regd = dp & 0x8000 ? regs.a[reg] : regs.d[reg];
if ((dp & 0x800) == 0)
regd = (LONG)(WORD)regd;
regd <<= (dp >> 9) & 3;
if (dp & 0x100) {
LONG outer = 0;
if (dp & 0x80) base = 0;
if (dp & 0x40) regd = 0;
if ((dp & 0x30) == 0x20) base += (LONG)(WORD)nextiword();
if ((dp & 0x30) == 0x30) base += nextilong();
if ((dp & 0x3) == 0x2) outer = (LONG)(WORD)nextiword();
if ((dp & 0x3) == 0x3) outer = nextilong();
if ((dp & 0x4) == 0) base += regd;
if (dp & 0x3) base = get_long (base);
if (dp & 0x4) base += regd;
return base + outer;
} else {
return base + (LONG)((BYTE)dp) + regd;
}
}
#else
static __inline__ ULONG get_disp_ea (ULONG base)
{
UWORD dp = nextiword();
int reg = (dp >> 12) & 7;
LONG regd = dp & 0x8000 ? regs.a[reg] : regs.d[reg];
if ((dp & 0x800) == 0)
regd = (LONG)(WORD)regd;
return base + (BYTE)(dp) + regd;
}
#endif
extern void MakeSR(void);
extern void MakeFromSR(void);
extern void Exception(int, CPTR);
extern void dump_counts(void);
extern void m68k_move2c(int, ULONG *);
extern void m68k_movec2(int, ULONG *);
extern void m68k_divl (ULONG, ULONG, UWORD, CPTR);
extern void m68k_mull (ULONG, ULONG, UWORD);
extern void init_m68k (void);
extern void m68k_run(void);
extern void m68k_go(int);
extern void m68k_run_2(void);
extern void m68k_dumpstate(CPTR *);
extern void m68k_disasm(CPTR,CPTR *,int);
extern void m68k_reset(void);
extern void mmu_op (ULONG, UWORD);
extern void fpp_opp (ULONG, UWORD);
extern void fdbcc_opp (ULONG, UWORD);
extern void fscc_opp (ULONG, UWORD);
extern void ftrapcc_opp (ULONG,CPTR);
extern void fbcc_opp (ULONG, CPTR, ULONG);
extern void fsave_opp (ULONG);
extern void frestore_opp (ULONG);